/*
 * @Author: hongbin
 * @Date: 2023-08-07 18:46:31
 * @LastEditors: hongbin
 * @LastEditTime: 2023-08-09 15:14:42
 * @Description: 行星
 */

import { ThreeHelper } from "@/ThreeHelper";
import { CameraInject } from "@/decorators";
import { DotMaterial } from "@/shader/DotMaterial";
import { Points } from "three";
import { gsap } from "gsap";

@(CameraInject<typeof Planet>)
export class Planet {
    particle?: THREE.Points<THREE.BufferGeometry, THREE.ShaderMaterial>;
    private camera!: THREE.PerspectiveCamera;
    private cameraWrapper!: THREE.Object3D;

    constructor() {
        this.loadModel();
    }

    loadModel() {
        ThreeHelper.instance
            .loadDrc("/models/particles/planet.drc")
            .then((geo) => {
                console.log(geo);
                geo.setAttribute("aColor", geo.attributes.color);
                geo.deleteAttribute("color");
                geo.center();
                geo.rotateY(1.2);
                this.particle = new Points(
                    geo,
                    new DotMaterial(
                        {
                            near: 17,
                            far: -15,
                            fadeDistance: 4,
                            blur: 3,
                            baseParticleSize: 3,
                        },
                        {
                            USE_ACOLOR: true,
                        }
                    )
                );

                ThreeHelper.instance.add(this.particle);
                this.setAnimation();
            });
    }

    setAnimation() {
        const particle = this.particle;
        if (!particle) return;
        particle.position.y = 8;
        particle.position.x = -18;
        particle.position.z = -37;
        particle.scale.set(-1, 1, 1);

        const tl = gsap.timeline({
            scrollTrigger: {
                trigger: "#container",
                start: innerHeight * 0.4,
                end: innerHeight * 1.4,
                scrub: 1,
            },
        });

        tl.to(particle.position, { z: 20, y: 5 }, 0).to(particle.position, {
            z: 30,
        });
        tl.to(
            this.cameraWrapper.position,
            { z: -20, duration: 1 - 0.17 - 0.1 },
            0.17
        );
        tl.to(
            this.camera,
            {
                duration: 1 - 0.17 - 0.1,
                fov: 130,
                onUpdate: () => this.camera.updateProjectionMatrix(),
            },
            0.17
        );

        tl.to(
            this.camera,
            {
                duration: 0.1,
                fov: 55,
                onUpdate: () => this.camera.updateProjectionMatrix(),
            },
            0.9
        );
        tl.to(particle.position, { x: -40, duration: 0.1 }, 0.9);
    }
}
